package registry

import (
	"context"
	"encoding/json"
	"fmt"
	"net"

	"gitee.com/saroeleven/ginrcpv2/etcdmgr/etcdclient"
)

const (
	defaultTTL = 5 // 默认 5 秒
)

type etcdRegistry struct {
	ttl     int64
	leaseId string // 租约ID
}

func WithTTL(ttl int64) func(*etcdRegistry) {
	return func(reg *etcdRegistry) {
		reg.ttl = ttl
	}
}
func NewEtcdRegistry(opt ...func(*etcdRegistry)) *etcdRegistry {
	e := &etcdRegistry{
		ttl: defaultTTL,
	}
	for _, o := range opt {
		o(e)
	}
	return e
}

func (e *etcdRegistry) Register(ctx context.Context, service *Service) error {
	ip4, err := e.getLocalIp()
	if err != nil {
		return err
	}
	service.Addr = ip4 + service.Addr

	// create etcd client
	client, err := etcdclient.NewEtcdClient()
	if err != nil {
		return err
	}
	bs, _ := json.Marshal(service)

	registryKey := fmt.Sprintf("%s/%s/%s", XnodePrefix, service.Name, service.Addr)
	return client.Register(ctx, registryKey, string(bs), e.ttl)
}

func (e *etcdRegistry) Deregister(ctx context.Context, service *Service) error {
	return nil
}

// getLocalIp tries to get the local IPv4 address of the machine.
func (*etcdRegistry) getLocalIp() (string, error) {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return "", err
	}
	for _, addr := range addrs {
		ipNet, ok := addr.(*net.IPNet)
		if ok && !ipNet.IP.IsLoopback() {
			if ipv4 := ipNet.IP.To4(); ipv4 != nil {
				return ipv4.String(), nil
			}
		}
	}

	return "", fmt.Errorf("no valid IPv4 found")
}
